package com.itheima.service.db.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.deser.std.NullifyingDeserializer;
import com.itheima.domain.db.AnalysisByDay;
import com.itheima.domain.vo.AnalysisSummaryVo;
import com.itheima.mapper.AnalysisByDayMapper;
import com.itheima.mapper.LogMapper;
import com.itheima.service.db.AnalysisByDayService;
import com.itheima.util.ComputeUtil;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.Date;

@Service // dubbo的
public class AnalysisByDayServiceImpl implements AnalysisByDayService {

    @Autowired
    private LogMapper logMapper;

    @Autowired
    private AnalysisByDayMapper analysisByDayMapper;

    @Override
    public void analysis() {
        // 1.准备基础数据
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();

        // 2.查询日志数据
        Integer numRegistered = logMapper.findByTimeAndType(today, "0102"); // 今日注册
        Integer numActive = logMapper.findByTime(today);// 今日活跃
        Integer numLogin = logMapper.findByTimeAndType(today, "0101");// 今日登陆
        Integer numRetention1d = logMapper.findByActive(today, yesterday);// 次日留存

        // 3.封装分析数据并完成保存
        // 3-1 先查询
        QueryWrapper<AnalysisByDay> qw = new QueryWrapper<>();
        qw.eq("record_date", today);
        AnalysisByDay analysisByDay = analysisByDayMapper.selectOne(qw);
        if (analysisByDay == null) { // 3-2新增
            analysisByDay = new AnalysisByDay();
            analysisByDay.setRecordDate(new Date());
            analysisByDay.setNumRegistered(numRegistered);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1d);
            // 注意这里是新增
            analysisByDayMapper.insert(analysisByDay);
        } else { // 3-3 修改
            analysisByDay.setNumRegistered(numRegistered);
            analysisByDay.setNumActive(numActive);
            analysisByDay.setNumLogin(numLogin);
            analysisByDay.setNumRetention1d(numRetention1d);

            // 注意这里是更新。。
            analysisByDayMapper.updateById(analysisByDay);
        }
    }

    @Override
    public AnalysisSummaryVo findAnalysisSummaryVo() {
        // 1.准备基础数据
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();
        String today_7 = DateUtil.offsetDay(new Date(), -7).toDateStr();
        String today_30 = DateUtil.offsetDay(new Date(), -30).toDateStr();
        // 查询今天的分析数据
        AnalysisByDay todayAnalysisData = analysisByDayMapper.selectOne(new QueryWrapper<AnalysisByDay>().eq("record_date", today));
        // 查询昨天的分析数据
        AnalysisByDay yesterdayAnalysisData = analysisByDayMapper.selectOne(new QueryWrapper<AnalysisByDay>().eq("record_date", yesterday));

        // 2.凑齐9份数据
        //累计用户数
        Long cumulativeUsers = analysisByDayMapper.findRegisteredCount();
        //过去30天活跃用户数
        Long activePassMonth = analysisByDayMapper.findActiveCount(today_30, today);
        //过去7天活跃用户
        Long activePassWeek = analysisByDayMapper.findActiveCount(today_7, today);
        //今日新增用户数量
        Long newUsersToday = todayAnalysisData.getNumRegistered().longValue();
        //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌   BigDecimal : 商业数字格式
        BigDecimal newUsersTodayRate = ComputeUtil.computeRate(todayAnalysisData.getNumRegistered(), yesterdayAnalysisData.getNumRegistered());
        //今日登录次数
        Long loginTimesToday = todayAnalysisData.getNumLogin().longValue();
        //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
        BigDecimal loginTimesTodayRate = ComputeUtil.computeRate(todayAnalysisData.getNumLogin(), yesterdayAnalysisData.getNumLogin());
        //今日活跃用户数量
        Long activeUsersToday = todayAnalysisData.getNumActive().longValue();
        //今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        BigDecimal activeUsersTodayRate = ComputeUtil.computeRate(todayAnalysisData.getNumActive(), yesterdayAnalysisData.getNumActive());
        // 3.封装并返回vo
        AnalysisSummaryVo analysisSummaryVo = new AnalysisSummaryVo();
        analysisSummaryVo.setCumulativeUsers(cumulativeUsers);
        analysisSummaryVo.setActivePassMonth(activePassMonth);
        analysisSummaryVo.setActivePassWeek(activePassWeek);
        analysisSummaryVo.setNewUsersToday(newUsersToday);
        analysisSummaryVo.setNewUsersTodayRate(newUsersTodayRate);
        analysisSummaryVo.setLoginTimesToday(loginTimesToday);
        analysisSummaryVo.setLoginTimesTodayRate(loginTimesTodayRate);
        analysisSummaryVo.setActiveUsersToday(activeUsersToday);
        analysisSummaryVo.setActiveUsersTodayRate(activeUsersTodayRate);
        return analysisSummaryVo;
    }
}
